package li.teng.joy.xcr.android;

public class Ssdp {
	public static String SDDP_ADDRESS = "239.255.255.250";
    public static int SDDP_PORT = 1900;
    public int MX;
    public SearchTarget ST;
    public String DeviceUUID;
    public MessageType messageType;
    
    public static Ssdp Parse(byte[] buffer,int length)
    {
    	Ssdp ret = new Ssdp();
        String txt = new String(buffer, 0, length);
        try
        {
            if (txt.startsWith("M-SEARCH"))
            {
                ret.messageType = MessageType.SearchRequest;
                ret.ParseSearchRequest(txt);
            }
            if (txt.startsWith("HTTP/1.1 200 OK"))
            {
                ret.messageType = MessageType.SearchResponse;
                ret.ParseSearchResponse(txt);
            }
            if (txt.startsWith("NOTIFY"))
            {
                ret.ParseNotify(txt);
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        return ret;
    }
    
    public byte[] GetCommandBytes()
    {
        String cmd = "";
        if (messageType == MessageType.SearchRequest) cmd = BuildSearchRequest();
        if (messageType == MessageType.SearchResponse) cmd = BuildSearchResponse();
        if (messageType == MessageType.Alive) cmd = BuildAlive();
        if (messageType == MessageType.Byebye) cmd = BuildByebye();
        return cmd.getBytes();
    }

    /*
    M-SEARCH * HTTP/1.1
    HOST: 239.255.255.250:1900
    MAN: "ssdp:discover"
    MX: seconds to delay response
    ST: search target
     */
    private String BuildSearchRequest(){
        String ret = "M-SEARCH * HTTP/1.1" + "\r\n" + "HOST: 239.255.255.250:1900" + "\r\n" + "MAN: \"ssdp:discover\"" + "\r\n";;
        ret += BuildST();
        return ret;
    }

    private String BuildST(){
        String ret = "ST:";
        if (ST == SearchTarget.SDDP_ALL)
        {
            ret += "ssdp:all";
        }
        if (ST == SearchTarget.UPNP_ROOTDEVICE)
        {
            ret += "upnp:rootdevice";
        }
        if (ST == SearchTarget.UUID)
        {
            ret += "uuid:" + DeviceUUID;
        }
        ret += "\r\n";
        return ret;
    }

    private void ParseSearchRequest(String txt)
    {
        String[] lines = txt.split("\r\n");// }, StringsplitOptions.RemoveEmptyEntries);
        for (String line : lines)
        {
            if (line.startsWith("MX"))
            {
                this.MX = Integer.parseInt(line.split(":")[1]);//Parse(line.split(":")[1]);
            }
            if (line.startsWith("ST"))
            {
                ParseST(line);
            }
        }
    }

    private void ParseST(String line)
    {
        if (line.indexOf("ssdp:all") != -1)
        {
            this.ST = SearchTarget.SDDP_ALL;
        }
        if (line.indexOf("upnp:rootdevice") != -1)
        {
            this.ST = SearchTarget.UPNP_ROOTDEVICE;
        }
        if (line.indexOf("uuid:") != -1)
        {
            this.ST = SearchTarget.UUID;
            this.DeviceUUID = line.split(":")[2];
        }
    }

    public int MaxAge;
    public String Location;
    public String OSVersion;
    public String ProductVersion;
    public String USN;
    /*  
    HTTP/1.1 200 OK
    CACHE-CONTROL: max-age = seconds until advertisement expires
    DATE: when reponse was generated
    EXT:
    LOCATION: URL for UPnP description for root device
    SERVER: OS/Version UPNP/1.0 product/version
    ST: search target
    USN: advertisement UUID
     */
    private String BuildSearchResponse()
    {
        String ret = "HTTP/1.1 200 OK" + "\r\n" + "CACHE-CONTROL: max-age = " + MaxAge + "\r\n" + "DATE: " + "" + "\r\n";
        ret += "EXT:" + "\r\n" + "LOCATION:" + Location + "\r\n" + "SERVER:" + OSVersion + " UPNP/1.0 " + ProductVersion + "\r\n";
        ret += BuildST();
        ret += "USN:" + USN + "\r\n";
        return ret;
    }

    private void ParseSearchResponse(String txt)
    {
        String[] lines = txt.split("\r\n" );//}, StringsplitOptions.RemoveEmptyEntries);
        for (String line : lines)
        {
            if (line.startsWith("CACHE-CONTROL"))
            {
                try
                {
                    this.MaxAge = Integer.parseInt(line.split(":")[1]);//.split('=')[1]);
                }
                catch (Exception ex)
                {
                    ;
                }
            }
            if (line.startsWith("LOCATION"))
            {
                this.Location = line.split(":")[1].trim();
            }
            if (line.startsWith("SERVER"))
            {
                String server = line.split(":")[1].trim();
                String[] paras = server.split(" ");
                this.OSVersion = paras[0];
                if (paras.length >= 3)
                    this.ProductVersion = paras[2];
            }
            if (line.startsWith("ST"))
            {
                ParseST(line);
            }
            if (line.startsWith("USN"))
            {
                this.USN = line.split(":")[1].trim();
            }
        }
    }

    /* 
    NOTIFY * HTTP/1.1
    HOST: 239.255.255.250:1900
    CACHE-CONTROL: max-age = seconds until advertisement expires
    LOCATION: URL for UPnP description for root device
    NT: search target
    NTS: ssdp:alive
    USN: advertisement UUID
     */
    public String NTS;
    public String NT;
    private String BuildAlive()
    {
        NTS = "ssdp:alive";
        return BuildNotify();
    }

    private String BuildByebye()
    {
        NTS = "ssdp:byebye";
        return BuildNotify();
    }

    private String BuildNotify()
    {
        String ret = "NOTIFY * HTTP/1.1" + "\r\n" + "HOST: 239.255.255.250:1900" + "\r\n" + "CACHE-CONTROL: max-age = " + MaxAge + "\r\n";
        ret += "LOCATION:" + Location + "\r\n" + "NT:" + NT + "\r\n";
        ret += "NTS:" + NTS + "\r\n";
        ret += "USN:" + USN + "\r\n";
        return ret;
    }

    private void ParseNotify(String txt)
    {
    	//new String[] { "\r\n" }, StringsplitOptions.RemoveEmptyEntries
        String[] lines = txt.split("\r\n");
        for (String line : lines)
        {
            if (line.startsWith("CACHE-CONTROL"))
            {
                this.MaxAge = Integer.parseInt(line.split("=")[1]);// int.Parse(line.split(":")[1]);
            }
            if (line.startsWith("LOCATION"))
            {
                this.Location = line.split(":")[1].trim();
            }
            if (line.startsWith("NT"))
            {
                this.NT = line.split(":")[1].trim();
            }
            if (line.startsWith("NTS"))
            {
                this.NTS = line.split(":")[1].trim();
                if (NTS == "ssdp:alive")
                    this.messageType = MessageType.Alive;
                if (NTS == "ssdp:byebye")
                    this.messageType = MessageType.Byebye;
            }
            if (line.startsWith("USN"))
            {
                this.USN = line.split(":")[1].trim();
            }
        }
    }    
}
